"""
模拟器模块
提供时间模拟器和数值模拟器功能
"""

import datetime
import random
from datetime import timezone, timedelta
from typing import Any, Dict, Union


class TimeSimulator:
    """时间模拟器"""
    
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.format = config.get('format', 'yyyy-MM-dd HH:mm:ss')
        self.offset = config.get('offset', 0)  # 时间偏移，单位：秒
    
    def generate(self, field_path: str = None) -> str:
        """生成时间字符串"""
        # 获取当前时间（东8区）
        tz = timezone(timedelta(hours=8))
        now = datetime.datetime.now(tz)
        
        # 应用时间偏移
        target_time = now + timedelta(seconds=self.offset)
        
        # 根据格式生成时间字符串
        if self.format == 'timestamp_s':
            return str(int(target_time.timestamp()))
        elif self.format == 'timestamp_ms':
            return str(int(target_time.timestamp() * 1000))
        else:
            # 使用Java SimpleDateFormat格式
            formatted_time = self._format_time(target_time, self.format)
            return formatted_time
    
    def _format_time(self, dt: datetime.datetime, format_str: str) -> str:
        """格式化时间字符串，支持Python strftime和Java SimpleDateFormat格式"""
        # 检查是否是Java风格的格式（包含小写字母）
        if any(c.islower() and c.isalpha() for c in format_str):
            # Java SimpleDateFormat格式转换
            java_to_python = {
                'yyyy': '%Y',  # 4位年份
                'yy': '%y',    # 2位年份
                'MM': '%m',    # 月份
                'dd': '%d',    # 日期
                'HH': '%H',    # 24小时制小时
                'mm': '%M',    # 分钟
                'ss': '%S',    # 秒
                'SSS': '%f'    # 毫秒（需要特殊处理）
            }
            
            # 转换格式字符串
            python_format = format_str
            for java_fmt, python_fmt in java_to_python.items():
                python_format = python_format.replace(java_fmt, python_fmt)
            
            # 处理毫秒
            if 'SSS' in format_str:
                # 将毫秒格式化为3位数字
                python_format = python_format.replace('%f', f'{dt.microsecond // 1000:03d}')
            
            return dt.strftime(python_format)
        else:
            # 直接使用Python的strftime格式
            return dt.strftime(format_str)


class NumberSimulator:
    """数值模拟器"""

    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.mode = config.get('mode', 'random')  # 'random' 或 'increment'
        self.min_val = config.get('min', 0)
        self.max_val = config.get('max', 100)
        self.step = config.get('step', 1)
        self.output_format = config.get('outputFormat', 'decimal')  # 'hex' 或 'decimal'
        self.padding = config.get('padding', 0)  # 输出位数填充

    def generate(self, field_path: str) -> Union[str, int]:
        """生成数值"""
        if self.mode == 'random':
            value = random.randint(self.min_val, self.max_val)
        elif self.mode == 'increment':
            value = self._get_next_increment_value(field_path)
        else:
            raise ValueError(f"不支持的数值模拟器模式: {self.mode}")

        # 根据输出格式格式化
        if self.output_format == 'hex':
            if self.padding > 0:
                return f"0x{value:0{self.padding}x}"
            else:
                return f"0x{value:x}"
        else:  # decimal
            if self.padding > 0:
                return f"{value:0{self.padding}d}"
            else:
                return str(value)

    def _get_next_increment_value(self, field_path: str) -> int:
        """获取下一个递增值"""
        # 全局状态存储
        if not hasattr(NumberSimulator, '_states'):
            NumberSimulator._states = {}

        if field_path not in NumberSimulator._states:
            NumberSimulator._states[field_path] = self.min_val
        else:
            NumberSimulator._states[field_path] += self.step
            if NumberSimulator._states[field_path] > self.max_val:
                NumberSimulator._states[field_path] = self.min_val

        return NumberSimulator._states[field_path]


class LocationSimulator:
    """经纬度模拟器"""

    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.lat_range = config.get('lat_range', [30.0, 40.0])
        self.lng_range = config.get('lng_range', [120.0, 130.0])

    def generate(self, field_path: str = None) -> Dict[str, float]:
        """生成经纬度对"""
        lat = random.uniform(self.lat_range[0], self.lat_range[1])
        lng = random.uniform(self.lng_range[0], self.lng_range[1])
        return {'lat': lat, 'lng': lng}


def create_simulator(simulator_config: Dict[str, Any]) -> Union[TimeSimulator, NumberSimulator, LocationSimulator]:
    """创建模拟器实例"""
    simulator_type = simulator_config.get('type')

    if simulator_type == 'time':
        return TimeSimulator(simulator_config)
    elif simulator_type == 'num':
        return NumberSimulator(simulator_config)
    elif simulator_type == 'location':
        return LocationSimulator(simulator_config)
    else:
        raise ValueError(f"不支持的模拟器类型: {simulator_type}")

